﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using ENail.Domain.Core;
using ENail.Domain.Core.Contract.Services;
using Equation.Enterprise.Framework.Domain.Data;
using Equation.Enterprise.Utilities.DesignByContract;

namespace ENail.ApplicationServices
{
    public class EmployeeService : IEmployeeService
    {
        private readonly IRepository<Employee> _employeeRepository;

        public EmployeeService(IRepository<Employee> employeeRepository)
        {
            Check.Require(employeeRepository != null);

            this._employeeRepository = employeeRepository;
        }

        /// <summary>
        /// Helps view all employees on list view
        /// </summary>
        /// <returns>List of all employees</returns>
        public IList<Employee> GetAllEmployees()
        {
            var employees = _employeeRepository.List();

            if (employees==null)
                employees = new List<Employee>();
            
            Check.Ensure(employees!=null);

            return employees.ToList();
        }

        /// <summary>
        /// Helps view employees for search view
        /// </summary>
        /// <param name="where">Lambda condition to get employees</param>
        /// <returns></returns>
        public IList<Employee> GetEmployees(Expression<Func<Employee, bool>> @where)
        {
            var employees = _employeeRepository.List(@where);

            if (employees == null)
                employees = new List<Employee>();

            Check.Ensure(employees != null);

            return employees.ToList();
        }

        /// <summary>
        /// Helps view active employees only
        /// </summary>
        /// <returns>All active employees</returns>
        public IList<Employee> GetAllActiveEmployees()
        {
            var employees = _employeeRepository.List(x=>x.IsActive);

            if (employees == null)
                employees = new List<Employee>();

            Check.Ensure(employees != null);

            return employees.ToList();
        }

        /// <summary>
        /// Helps view details of an employee
        /// </summary>
        /// <param name="id">Identity of employee</param>
        /// <returns>Employee with specified identity</returns>
        public Employee GetEmployee(int id)
        {
            Check.Require(id>0);

            Employee employee = _employeeRepository.Get(id);
            
            return employee;
        }

        /// <summary>
        /// Insert an employee from view
        /// </summary>
        /// <param name="employee">Employee to be inserted</param>
        /// <returns>Number of records affected</returns>
        public int InsertEmployee(Employee employee)
        {
            Check.Require(employee!=null);

            _employeeRepository.Add(employee);
            return _employeeRepository.SaveChanges();
        }

        /// <summary>
        /// Update an employee from view
        /// </summary>
        /// <param name="employee">Employee to be updated</param>
        /// <returns>Number of records affected</returns>
        public int UpdateEmployee(Employee employee)
        {
            Check.Require(employee != null);

            _employeeRepository.Update(employee);
            return _employeeRepository.SaveChanges(); 
        }

        /// <summary>
        /// Helps to inactive an employee
        /// </summary>
        /// <param name="employee">Employee to be inactive</param>
        /// <returns>Number of records affected</returns>
        public int InActiveEmployee(Employee employee)
        {
            Check.Require(employee != null);

            employee.IsActive = false;
            _employeeRepository.Update(employee);
            return _employeeRepository.SaveChanges();
        }
    }
}
